<?php

class base_component_ui {

    var $base_dir = '';

    var $base_url = '';

    static $inputer = array();

    static $_ui_id = 0;

    var $_form_path = array();

    private $_imgbundle = array();

    private $_pageid = null;

    function __construct($controller, $app_specal = null) {
        $this->controller = $controller;
        if ($app_specal) {
            $this->app = $app_specal;
        } else {
            $this->app = $controller->app;
        }
    }

    function table_begin() {
        return '<table>';
    }

    function table_head($headers) {
        return '<thead><th>' . implode('</th><th>', $headers) . '</th></thead>';
    }

    function table_colset() {}

    function table_panel($html) {
        return '<div>' . implode('', $html) . '</div>';
    }

    function table_rows($rows) {
        foreach ($rows as $row) {
            $return[] = '<tr>';
            foreach ($row as $k => $v) {
                $return[] = $v;
            }
            $return[] = '</tr>';
        }
        return implode('', $return);
    }

    function table_end() {
        return '</table>';
    }

    function img($params) {
        if (is_string($params)) {
            $params = array(
                'src' => $params
            );
        }
        $app = $params['app'] ? app::get($params['app']) : $this->app;
        
        if (! isset($this->_imgbundle[$app->app_id])) {
            $bundleinfo = array();
            // base_kvstore::instance('imgbundle')->fetch('imgbundle_' . $app->app_id, $bundleinfo);
            $this->_imgbundle[$app->app_id] = (array) $bundleinfo;
        }
        
        if (is_array($this->_imgbundle[$app->app_id]['info']) && array_key_exists($params['src'], $this->_imgbundle[$app->app_id]['info'])) {
            $img_info = $this->_imgbundle[$app->app_id]['info'][$params['src']];
            $params['lib'] = kernel::base_url(1) . '/' . $this->_imgbundle[$app->app_id]['bundleimg'] . '?' . $this->_imgbundle[$app->app_id]['mtime'];
            $params['src'] = app::get('base')->res_url . '/transparent.gif';
            $style = "background-image:url({$params['lib']});background-position:0 {$img_info[0]}px;width:{$img_info[1]}px;height:{$img_info[2]}px";
            $params['style'] = $params['style'] ? ($params['style'] . ';' . $style) : $style;
            $params['class'] = $params['class'] ? ('imgbundle ' . $params['class']) : 'imgbundle';
        } else {
            $params['src'] = $app->res_url . '/' . $params['src'];
        }
        unset($params['lib']);
        return utils::buildTag($params, 'img');
    }

    function input($params) {
        if ($params['params']) {
            $p = $params['params'];
            unset($params['params']);
            $params = array_merge($p, $params);
        }
        
        if (is_array($params['type'])) {
            $params['options'] = $params['type'];
            $params['type'] = 'select';
        }
        if (! array_key_exists('value', $params) && array_key_exists('default', $params)) {
            $params['value'] = $params['default'];
        }
        if (! $params['id']) {
            $params['id'] = $this->new_dom_id();
        }
        
        if (substr($params['type'], 0, 6) == 'table:') {
            list (, $params['object'], $params['app']) = preg_split('/[:|@]/', $params['type']);
            $params['type'] = 'object';
            if ($params['name'] == 'cat_id') {
                $params['type'] = 'goodscat';
                return $this->input_element('goodscat', $params);
            }
            if ($this->input_element('object_' . $params['type'])) {
                return $this->input_element('object_' . $params['type'], $params);
            } else {
                return $this->input_element('object', $params);
            }
        } elseif ($this->input_element($params['type'])) {
            return $this->input_element($params['type'], $params);
        } else {
            return $this->input_element('default', $params);
        }
    }

    function input_element($type, $params = false) {
        if (! base_component_ui::$inputer) {
            if (kernel::is_online()) {
                base_component_ui::$inputer = kernel::servicelist('html_input');
            } else {
                base_component_ui::$inputer = array(
                    'base_view_input' => new base_view_input()
                );
            }
        }
        
        if ($params === false) {
            foreach (base_component_ui::$inputer as $inputer) {
                $inputer->app = $this->app;
                if (method_exists($inputer, 'input_' . $type)) {
                    return true;
                }
            }
        } else {
            foreach (base_component_ui::$inputer as $inputer) {
                
                $inputer->app = $this->app;
                if (method_exists($inputer, 'input_' . $type)) {
                    
                    $html = $inputer->{'input_' . $type}($params);
                }
            }
            return $html;
        }
        return false;
    }

    function form_start($params = null) {
        if (is_string($params)) {
            $params = array(
                'action' => $params
            );
        }
        if (! $params['action']) {
            $params['action'] = 'index.php?' . $_SERVER['QUERY_STRING'];
        }
        
        array_unshift($this->_form_path, $params);
        
        $return = '';
        if ($params['title']) {
            $return .= '<h4>' . $params['title'] . '</h4>';
            unset($params['title']);
        }
        
        $return .= '<div class="tableform' . ($params['tabs'] ? ' tableform-tabs' : '') . '">';
        
        if ($params['tabs']) {
            
            $this->form_tab_html = array();
            $dom_tab_ids = array();
            $current = false;
            
            foreach ($params['tabs'] as $k => $tab) {
                $dom_id = $this->new_dom_id();
                $dom_tab_ids[$k] = $dom_id;
                if ($current) {
                    $style = 'style="display:none"';
                } else {
                    $style = '';
                    $current = true;
                }
                $this->form_tab_html[$k] = '<div class="division" id="' . $dom_id . '" ' . $style . '><table width="100%" cellspacing="0" cellpadding="0">';
            }
            
            $return .= '<div class="tabs-wrap clearfix"><ul>';
            $current = false;
            foreach ($params['tabs'] as $k => $tab) {
                if ($current) {
                    $style = '';
                } else {
                    $style = ' current';
                    $current = true;
                }
                $return .= '<li id="_' . $dom_tab_ids[$k] . '" class="tab' . $style . '" onclick="setTab([\'' . $dom_tab_ids[$k] . '\',[\'' . implode('\',\'', $dom_tab_ids) . '\']],[\'current\'])"><span>' . $tab . '</span></li>';
            }
            $return .= '</ul>';
            
            $this->_form_path[0]['element_started'] = true;
        }
        
        return utils::buildTag($params, 'form', false) . $return;
    }

    function form_input($params) {
        if (! isset($params['id'])) {
            $params['id'] = $this->new_dom_id();
        }
        if (isset($params['tab'])) {
            $tab = $params['tab'];
            unset($params['tab']);
        }
        
        $return = '';
        
        if (! $this->_form_path[0]['element_started']) {
            $return .= <<<EOF
    <div class="division">
        <table width="100%" cellspacing="0" cellpadding="0">
EOF;
            $this->_form_path[0]['element_started'] = true;
        }
        if ($params['helpinfo'])
            $span = '<label class="help">' . $params['helpinfo'] . '</label>';
        else
            $span = '';
        if (isset($params['style']) && $params['style'] && $params['style'] == 'display:none;') {
            $return .= '<tr style="display:none;"><th>' . ($params['required'] ? '<em class="red">*</em>' : '') . '<label for="' . $params['id'] . '">' . $params['title'] . '</label>' . '</th><td>' . $this->input($params) . $span . '</td></tr>';
        } else
            $return .= '<tr><th>' . ($params['required'] ? '<em class="red">*</em>' : '') . '<label for="' . $params['id'] . '">' . $params['title'] . '</label>' . '</th><td>' . $this->input($params) . $span . '</td></tr>';
        if (isset($this->form_tab_html[$tab])) {
            $this->form_tab_html[$tab] .= $return;
            return '';
        } else {
            return $return;
        }
    }

    static function new_dom_id() {
        return 'dom_el_' . substr(md5(time()), 0, 6) . intval(self::$_ui_id++);
    }

    function form_end($options = array()) {
        $has_ok_btn = isset($options['has_ok_btn']) ? (bool) $options['has_ok_btn'] : true;
        $btn_txt = isset($options['btn_txt']) ? $options['btn_txt'] : '确定';
        if ($this->_form_path[0]['element_started']) {
            $return .= '</table></div>';
        }
        
        foreach ((array) $this->form_tab_html as $html) {
            $return .= $html . '</table></div>';
        }
        
        if ($has_ok_btn) {
            $return .= '<div class="table-action">' . $this->button(array(
                'type' => 'submit',
                'class' => 'btn-primary',
                'label' => $btn_txt
            )) . '</div>';
        }
        ;
        
        array_shift($this->_form_path);
        if ($this->form_tab_html) {
            $return .= '</div>';
        }
        $return .= '</div></form>';
        $this->form_tab_html = null;
        return $return;
    }

    function button($params) {
        if ($params['class']) {
            $params['class'] = 'btn ' . $params['class'];
        } else {
            $params['class'] = 'btn';
        }
        
        if ($params['icon']) {
            $icon = '<i class="icon ' . $params['icon'] . '"></i>';
            $params['class'] .= ' btn-has-icon';
            unset($params['icon']);
        }
        if ($params['icon_l']) {
            $icon_l = '<q class="icon">' . $params['icon_l'] . '</q>';
            // $params['class'] .= ' btn-has-icon';
            unset($params['icon_l']);
        }
        if ($params['icon_r']) {
            $icon_r = '<q class="f-icon">' . $params['icon_r'] . '</q>';
            // $params['class'] .= ' btn-has-icon';
            unset($params['icon_r']);
        }
        
        $app = $params['app'] ? app::get($params['app']) : $this->app;
        
        if ($params['label']) {
            $label = htmlspecialchars($app->_($params['label']));
            unset($params['label']);
        }
        
        $type = $params['type'];
        if ($type == 'link') {
            $element = 'a';
            unset($params['link']);
        } else {
            $element = 'button';
            if ($params['href'] && ! strpos($params['href'], 'javascript:')) {
                $params['onclick'] = 'W.page(\'' . $params['href'] . '\')';
                unset($params['href']);
            }
            if ($type != 'submit') {
                $params['type'] = 'button';
            }
        }
        
        if ($params['dropmenu']) {
            if (! $params['id']) {
                $params['id'] = $this->new_dom_id();
            }
            
            if ($type != 'dropmenu') {
                $element = 'span';
                $class .= ' btn-drop-menu drop-active';
                $drop_handel_id = $params['id'] . '-handel';
                $dropmenu = '<img dropfor="' . $params['id'] . '"
                    id="' . $drop_handel_id . '" dropmenu=' . $params['dropmenu'] . ' src="' . app::get('base')->res_url . '/transparent.gif" class="drop-handle drop-handle-stand" />';
                unset($params['dropmenu']);
            } else {
                $drop_handel_id = $params['id'];
                $dropmenu = '<img src="' . app::get('base')->res_url . '/transparent.gif" class="drop-handle" />';
            }
            $scripts = '<script>new DropMenu("' . $drop_handel_id . '",{' . $params['dropmenu_opts'] . '});';
            $scripts .= '</script>';
        }
        
        return utils::buildTag($params, $element, 0) . '<span><span>' . $icon . $icon_l . $label . $dropmenu . $icon_r . '</span></span></' . $element . '>' . $scripts;
    }

    function getVer($flag = true, $ver = null) {
        return $flag ? '?' . substr(cachemgr::ask_cache_check_version(true), 0, 6) : ($ver ? '?' . $ver : '');
    }

    function script($params) {
        $app = $params['app'] ? app::get($params['app']) : $this->app; // todo：APP机制了，每个APP自己控制
        
        $debug = defined('DEBUG_JS') && constant('DEBUG_JS');
        if ($params['pdir'] && ! $debug) {
            $pdir = $params['pdir'];
        } else {
            $pdir = 'js';
        }
        
        if (is_dir($app->res_dir . '/' . $pdir))
            $file = $app->res_url . '/' . $pdir . '/' . $params['src'];
        else
            $file = $app->res_url . '/' . $params['src'];
        if ($params['content']) {
            return '<script>' . file_get_contents($file) . '</script>';
        } else {
            $version = $this->getVer($debug);
            return '<script src="' . $file . $version . '"></script>';
        }
    }

    function css($params) {
        $default = array(
            'rel' => 'stylesheet'
        );
        $app = $params['app'] ? app::get($params['app']) : $this->app;
        $debug = defined('DEBUG_CSS') && constant('DEBUG_CSS');
        if ($params['pdir'] && ! $debug) {
            $pdir = $params['pdir'];
        } else {
            $pdir = 'css';
        }
        
        if (is_dir($app->res_dir . '/' . $pdir))
            $file = $app->res_url . '/' . $pdir . '/' . $params['src'];
        else
            $file = $app->res_url . '/' . $params['src'];
        
        if (isset($params['pdir']))
            unset($params['pdir']);
        if (isset($params['src']))
            unset($params['src']);
        if (isset($params['app']))
            unset($params['app']);
        $params = count($params) ? $params + $default : $default;
        foreach ($params as $k => $v) {
            $ext .= sprintf('%s="%s" ', $k, $v);
        }
        $version = $this->getVer($debug);
        return sprintf('<link href="%s" %s/>', $file . $version, $ext);
    }
 // End Function
    function tree($option) {
        $model = isset($option['model']) && $option['model'] ? $option['model'] : '';
        $template = isset($option['template']) && $option['template'] ? $option['template'] : '%2$s';
        $pagelimit = 20;
        
        $model = $this->app->model($model);
        $pid = intval($_GET['tree']['pid']);
        $offset = intval($_GET['tree']['p']);
        
        foreach ($model->schema['columns'] as $k => $col) {
            if ($col['parent_id']) {
                $pid_col = $k;
            }
        }
        
        $items = $model->getList($model->idColumn . ',' . $model->textColumn, array(
            $pid_col => $pid
        ), $offset, $pagelimit);
        foreach ($items as $item) {
            $html .= sprintf('<span class="node node-hasc" item="%1$d">
                <span class="node-handle">&nbsp;</span>' . $template . '</span>', $item[$model->idColumn], $item[$model->textColumn]);
        }
        
        $count = $model->count(array(
            $pid_col => $pid
        ));
        $current = $offset + count($items);
        if ($count > $current) {
            $html .= '<div><span class="more" pid="' . $pid . '" more="' . ($current) . '">' . ($count - $current) . app::get('base')->_('个未显示') . '&hellip;</span></div>';
        }
        
        if ($_GET['act'] == 'treenode') {
            return $html;
        } else {
            $new_dom_id = $this->new_dom_id();
            $params = json_encode(array(
                'args' => func_get_args()
            ));
            return <<<EOF
<div class="x-tree-list" id="{$new_dom_id}" child="{$count}">{$html}</div>
<script>
init_tree($('{$new_dom_id}'),{$params});
</script>
EOF;
        }
    }

    function pager($params) {
        if (substr($params['link'], 0, 11) == 'javascript:') {
            $tag = 'span';
            $this->pager_attr = 'onclick';
            $params['link'] = substr($params['link'], 11);
        } else {
            $tag = 'a';
            $this->pager_attr = 'href';
        }
        
        $this->pager_tag = $tag;
        
        if (! $params['current'])
            $params['current'] = 1;
        if (! $params['total'])
            $params['total'] = 1;
        if ($params['total'] < 2) {
            return '';
        }
        
        if (! $params['nobutton']) {
            if ($params['current'] > 1) {
                $prev = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], $params['current'] - 1) . '" class="prev">&laquo;</' . $tag . '>';
            } else {
                $prev = '<span class="prev disabled">&laquo;</span>';
            }
            
            if ($params['current'] < $params['total']) {
                $next = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], $params['current'] + 1) . '" class="next">&raquo;</' . $tag . '>';
            } else {
                $next = '<span class="next disabled">&raquo;</span>';
            }
        }
        
        $c = $params['current'];
        $t = $params['total'];
        $v = array();
        $l = $params['link'];
        ;
        
        if ($t < 11) {
            $v[] = $this->pager_link(1, $t, $l, $c);
            // 123456789
        } else {
            if ($t - $c < 8) {
                $v[] = $this->pager_link(1, 3, $l);
                $v[] = $this->pager_link($t - 8, $t, $l, $c);
                // 12..50 51 52 53 54 55 56 57
            } elseif ($c < 10) {
                $v[] = $this->pager_link(1, max($c + 3, 10), $l, $c);
                $v[] = $this->pager_link($t - 1, $t, $l);
                // 1234567..55
            } else {
                $v[] = $this->pager_link(1, 3, $l);
                $v[] = $this->pager_link($c - 2, $c + 3, $l, $c);
                $v[] = $this->pager_link($t - 1, $t, $l);
                // 123 456 789
            }
        }
        $links = implode('&hellip;', $v);
        
        return <<<EOF
    <div class="pager">
     <div class="pagernum">
      {$prev}{$links}{$next}
     </div>
    </div>
EOF;
    }

    private function pager_link($from, $to, $l, $c = null) {
        for ($i = $from; $i < $to + 1; $i++) {
            if ($c == $i) {
                $r[] = ' <span class="current">' . $i . '</span> ';
            } else {
                $r[] = ' <' . $this->pager_tag . ' ' . $this->pager_attr . '="' . sprintf($l, $i) . '">' . $i . '</' . $this->pager_tag . '> ';
            }
        }
        return implode(' ', $r);
    }

    function lang_script($params) {
        $app = $params['app'] ? app::get($params['app']) : $this->app;
        $lang = kernel::get_lang();
        
        $debug = defined('DEBUG_JS') && constant('DEBUG_JS');
        if ($params['pdir'] && ! $debug) {
            $pdir = $params['pdir'];
        } else {
            $pdir = 'js';
        }
        
        $src = $pdir . '/' . $params['src'];
        
        if (is_array($app->lang_resource($lang)) && in_array($src, $app->lang_resource($lang))) {
            $file = $app->lang_url . '/' . $lang . '/' . $src;
        } elseif (is_array($app->lang_resource('zh_CN')) && in_array($src, $app->lang_resource('zh_CN'))) {
            $file = $app->lang_url . '/zh_CN/' . $src;
        } else {
            return '';
        }
        
        if ($params['content']) {
            return '<script>' . file_get_contents($file) . '</script>';
        } else {
            $version = $this->getVer($debug);
            return '<script src="' . $file . $version . '"></script>';
        }
    }

    function lang_css($params) {
        $default = array(
            'rel' => 'stylesheet'
        );
        $app = $params['app'] ? app::get($params['app']) : $this->app;
        $lang = kernel::get_lang();
        
        $debug = defined('DEBUG_CSS') && constant('DEBUG_CSS');
        if ($params['pdir'] && ! $debug) {
            $pdir = $params['pdir'];
        } else {
            $pdir = 'css';
        }
        
        $src = $pdir . '/' . $params['src'];
        if (is_array($app->lang_resource($lang)) && in_array($src, $app->lang_resource($lang))) {
            $file = $app->lang_url . '/' . $lang . '/' . $src;
        } elseif (is_array($app->lang_resource('zh_CN')) && in_array($src, $app->lang_resource('zh_CN'))) {
            $file = $app->lang_url . '/zh_CN/' . $src;
        } else {
            return '';
        }
        if (isset($params['pdir']))
            unset($params['pdir']);
        if (isset($params['src']))
            unset($params['src']);
        if (isset($params['app']))
            unset($params['app']);
        $params = count($params) ? $params + $default : $default;
        foreach ($params as $k => $v) {
            $ext .= sprintf('%s="%s" ', $k, $v);
        }
        $version = $this->getVer($debug);
        return sprintf('<link href="%s" %s/>', $file . $version, $ext);
    }
 // End Function
    public function pageid() {
        if (is_null($this->_pageid)) {
            $obj = kernel::single('base_component_request');
            $key = md5(sprintf('%s_%s_%s_%s', $obj->get_app_name(), $obj->get_ctl_name(), $obj->get_act_name(), serialize($obj->get_params())));
            $this->_pageid = base_convert(strtolower($key), 16, 10);
            $this->_pageid = substr($this->dec2any($this->_pageid), 4, 8);
        }
        return $this->_pageid;
    }
 // End Function
    private function dec2any($num, $base = 62, $index = false) {
        if (! $base) {
            $base = strlen($index);
        } else if (! $index) {
            $index = substr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base);
        }
        $out = "";
        for ($t = floor(log10($num) / log10($base)); $t >= 0; $t--) {
            $a = floor($num / pow($base, $t));
            $out = $out . substr($index, $a, 1);
            $num = $num - ($a * pow($base, $t));
        }
        return $out;
    }

    function desktoppager($params) {
        if (substr($params['link'], 0, 11) == 'javascript:') {
            $tag = 'span';
            $this->pager_attr = 'onclick';
            $params['link'] = substr($params['link'], 11);
        } else {
            $tag = 'a';
            $this->pager_attr = 'href';
        }
        
        $this->pager_tag = $tag;
        
        if (! $params['current'])
            $params['current'] = 1;
        if (! $params['total'])
            $params['total'] = 1;
        if ($params['total'] < 2) {
            return '';
        }
        
        if (! $params['nobutton']) {
            if ($params['current'] > 1) {
                $first = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], 1) . '" class=""><i class="fa fa-angle-double-left"></i></' . $tag . '>';
                $prev = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], $params['current'] - 1) . '" class="prev"><i class="fa fa-angle-left"></i></' . $tag . '>';
            } else {
                $first = '<span class="disabled"><i class="fa fa-angle-double-left"></i></span>';
                $prev = '<span class="prev disabled"><i class="fa fa-angle-left"></i></span>';
            }
            
            if ($params['current'] < $params['total']) {
                $next = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], $params['current'] + 1) . '" class="next"><i class="fa fa-angle-right"></i></' . $tag . '>';
                $last = '<' . $tag . ' ' . $this->pager_attr . '="' . sprintf($params['link'], $params['total']) . '" class=""><i class="fa fa-angle-double-right"></i></' . $tag . '>';
            } else {
                $next = '<span class="next disabled"><i class="fa fa-angle-right"></i></span>';
                $last = '<span class="disabled"><i class="fa fa-angle-double-right"></i></span>';
            }
        }
        
        $c = $params['current'];
        $t = $params['total'];
        $v = array();
        $l = $params['link'];
        ;
        
        if ($t < 11) {
            $v[] = $this->pager_link(1, $t, $l, $c);
            // 123456789
        } else {
            if ($t - $c < 8) {
                $v[] = $this->pager_link(1, 3, $l);
                $v[] = $this->pager_link($t - 8, $t, $l, $c);
                // 12..50 51 52 53 54 55 56 57
            } elseif ($c < 7) {
                $v[] = $this->pager_link(1, max($c + 3, 7), $l, $c);
                $v[] = $this->pager_link($t - 1, $t, $l);
                // 1234567..55
            } else {
                $v[] = $this->pager_link(1, 3, $l);
                $v[] = $this->pager_link($c - 2, $c + 3, $l, $c);
                $v[] = $this->pager_link($t - 1, $t, $l);
                // 123 456 789
            }
        }
        $links = implode('&hellip;', $v);
        
        return <<<EOF
    <div class="pager">
     <div class="pagernum">
      {$first}{$prev}{$links}{$next}{$last}
     </div>
    </div>
EOF;
    }
}
